package com.rest.interceptor;

import com.alibaba.fastjson.JSON;
import com.rest.common.Method;
import com.rest.exception.RRException;
import com.rest.model.DataM;
import com.rest.model.R;
import com.rest.service.DataMService;
import com.rest.util.LRUUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author 王战伟
 * @email mrwangzhanwei@163.com
 * @date 2021/3/16  14:44
 * ///////////////////////////////////////////////////////////////////
 * //                          _ooOoo_                               //
 * //                         o8888888o                              //
 * //                         88" . "88                              //
 * //                         (| ^_^ |)                              //
 * //                         O\  =  /O                              //
 * //                      ____/`---'\____                           //
 * //                    .'  \\|     |//  `.                         //
 * //                   /  \\|||  :  |||//  \                        //
 * //                  /  _||||| -:- |||||-  \                       //
 * //                  |   | \\\  -  /// |   |                       //
 * //                  | \_|  ''\---/''  |   |                       //
 * //                  \  .-\__  `-`  ___/-. /                       //
 * //                ___`. .'  /--.--\  `. . ___                     //
 * //              ."" '<  `.___\_<|>_/___.'  >'"".                  //
 * //            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
 * //            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
 * //      ========`-.____`-.___\_____/___.-`____.-'========         //
 * //                           `=---='                              //
 * //      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
 * //            佛祖保佑       永不宕机     永无BUG                   //
 * ////////////////////////////////////////////////////////////////////
 * 路径拦截器
 */
public class PathInterceptor implements HandlerInterceptor {

    @Autowired
    private DataMService dataMService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws Exception{
        AtomicBoolean state = new AtomicBoolean(true);

        // 获取请求路径
        String uri = request.getRequestURI();
        // 从缓存中获取
        DataM data = Optional.ofNullable(LRUUtil.get(uri)).orElseGet(() ->{
            // 查询数据库
            DataM dataM = dataMService.getDataByUrl(uri);
            // 添加到缓存
            LRUUtil.put(uri,dataM);
            return dataM;
        });
        // 再次判断数据是否为空 不为空进入逻辑
        Optional.ofNullable(data).ifPresent(dataM -> {
            // 获取请求方式
            String method = request.getMethod();
            try{
                // 检查请求方式是否支持
                Assert.notNull(Method.getMethod(method.toUpperCase()),"目前只支持 " + Method.getAllMethod());
                // 检查请求方式是否正确
                Assert.isTrue(method.toUpperCase().equals(data.getMethod().toUpperCase()),
                                "请求方式应该是 "+ data.getMethod().toUpperCase());
                // 校验参数
                Assert.isTrue(verifiParameters(request.getParameterNames()),"参数不正确,你再看看");
                // 输出数据
                printData(request,response,data.getData());
            }catch (Exception e){
                printData(request,response,JSON.toJSONString(R.error(e.getMessage())));
            }finally {
                state.set(false);
            }

        });
        return state.get();
    }

    /**
     * 校验参数
     * @param parameterNames
     * @return
     */
    private boolean verifiParameters(Enumeration<String> parameterNames) {

        return true;
    }

    /**
     * 输出结果
     * @param request
     * @param response
     * @param json
     * @throws IOException
     */
    private void printData(HttpServletRequest request,HttpServletResponse response,String json){
        response.setContentType(request.getContentType() == null ? "application/json;charset=UTF-8":request.getContentType());
        try {
            response.getWriter().print(json);
            response.getWriter().flush();
            response.getWriter().close();
        }catch (IOException e){
            e.printStackTrace();
        }

    }

}
